package com.talkweb.osmharmony.views.util;

import com.talkweb.osmharmony.util.BoundingBox;
import com.talkweb.osmharmony.util.GeoPoint;
import com.talkweb.osmharmony.util.PointL;
import com.talkweb.osmharmony.util.TileSystem;
import com.talkweb.osmharmony.views.Projection;
import com.talkweb.osmharmony.views.overlay.Polygon;
import com.talkweb.osmharmony.views.overlay.Polyline;

import ohos.agp.render.Path;
import ohos.agp.utils.Point;
import ohos.agp.utils.Rect;

import java.util.List;

/**
 * @deprecated Use {@link Polyline} or {@link Polygon} instead
 */
@Deprecated
public class PathProjection {

    public static Path toPixels(Projection projection, final List<? extends GeoPoint> in,
                                final Path reuse) {
        return toPixels(projection, in, reuse, true);
    }

    public static Path toPixels(Projection projection, final List<? extends GeoPoint> in,
                                final Path reuse, final boolean doGudermann) throws IllegalArgumentException {
        if (in.size() < 2) {
            throw new IllegalArgumentException("List of GeoPoints needs to be at least 2.");
        }

        final Path out = (reuse != null) ? reuse : new Path();
        out.incReserve(in.size());

        final TileSystem tileSystem = com.talkweb.osmharmony.views.MapView.getTileSystem();
        boolean first = true;
        for (final GeoPoint gp : in) {
            final Point underGeopointTileCoords = new Point();
            final double mapSize = TileSystem.MapSize(projection.getZoomLevel());
            final PointL mercator = tileSystem.getMercatorFromGeo(
                    gp.getLatitude(), gp.getLongitude(), mapSize,
                    null, true);
            underGeopointTileCoords.modify(projection.getTileFromMercator(mercator.x), projection.getTileFromMercator(mercator.y));

            /*
             * Calculate the Latitude/Longitude on the left-upper ScreenCoords of the MapTile.
             */
            final PointL upperRight = new PointL(
                    projection.getMercatorFromTile(underGeopointTileCoords.getPointXToInt()),
                    projection.getMercatorFromTile(underGeopointTileCoords.getPointYToInt()));
            final PointL lowerLeft = new PointL(
                    projection.getMercatorFromTile(underGeopointTileCoords.getPointXToInt() + TileSystem.getTileSize()),
                    projection.getMercatorFromTile(underGeopointTileCoords.getPointYToInt() + TileSystem.getTileSize()));
            final GeoPoint neGeoPoint = tileSystem.getGeoFromMercator(upperRight.x, upperRight.y, mapSize, null, true, true);
            final GeoPoint swGeoPoint = tileSystem.getGeoFromMercator(lowerLeft.x, lowerLeft.y, mapSize, null, true, true);
            final BoundingBox bb = new BoundingBox(neGeoPoint.getLatitude(),
                    neGeoPoint.getLongitude(), swGeoPoint.getLatitude(),
                    swGeoPoint.getLongitude());

            final Point relativePositionInCenterMapTile;
            if (doGudermann && (projection.getZoomLevel() < 7)) {
                relativePositionInCenterMapTile = bb
                        .getRelativePositionOfGeoPointInBoundingBoxWithExactGudermannInterpolation(
                                gp.getLatitude(), gp.getLongitude(), null);
            } else {
                relativePositionInCenterMapTile = bb
                        .getRelativePositionOfGeoPointInBoundingBoxWithLinearInterpolation(
                                gp.getLatitude(), gp.getLongitude(), null);
            }

            final Rect screenRect = projection.getScreenRect();
            final Point centerMapTileCoords = new Point(
                    projection.getTileFromMercator(screenRect.getCenterX()),
                    projection.getTileFromMercator(screenRect.getCenterY()));
            final PointL upperLeftCornerOfCenterMapTile = new PointL(
                    projection.getMercatorFromTile(centerMapTileCoords.getPointXToInt()),
                    projection.getMercatorFromTile(centerMapTileCoords.getPointYToInt()));
            final int tileDiffX = centerMapTileCoords.getPointXToInt() - underGeopointTileCoords.getPointXToInt();
            final int tileDiffY = centerMapTileCoords.getPointYToInt() - underGeopointTileCoords.getPointYToInt();
            final long underGeopointTileScreenLeft = upperLeftCornerOfCenterMapTile.x
                    - (TileSystem.getTileSize() * tileDiffX);
            final long underGeopointTileScreenTop = upperLeftCornerOfCenterMapTile.y
                    - (TileSystem.getTileSize() * tileDiffY);

            final long x = underGeopointTileScreenLeft
                    + (long) (relativePositionInCenterMapTile.getPointX() * TileSystem.getTileSize());
            final long y = underGeopointTileScreenTop
                    + (long) (relativePositionInCenterMapTile.getPointY() * TileSystem.getTileSize());

            /* Add up the offset caused by touch. */
            if (first) {
                out.moveTo(x, y);
                // out.moveTo(x + MapView.this.mTouchMapOffsetX, y +
                // MapView.this.mTouchMapOffsetY);
            } else {
                out.lineTo(x, y);
            }
            first = false;
        }

        return out;
    }
}
